package com.huixh.train.utils.security;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author huixh
 */
@Component
public class JwtUtil {
    private final Logger logger = LoggerFactory.getLogger(JwtUtil.class);

    @Value("${jwt.key:default}")
    private String key;

    private static final String DEFAULT_KEY = "default";

    @PostConstruct
    private void verifyKey() {
        if (StrUtil.equals(key, DEFAULT_KEY)) {
            logger.warn("没有设置指定 jwt.key 将默认使用: {}", DEFAULT_KEY);
        }
    }

    public String createToken(Long id, String mobile) {
        byte[] bytes = key.getBytes();
        DateTime now = DateTime.now();
        DateTime expiresAt = now.offsetNew(DateField.HOUR, 24);
        JWT jwt = JWT.create()
                .setKey(bytes)
                .setPayload("id", id)
                .setPayload("mobile", mobile)
                .setExpiresAt(expiresAt)
                .setIssuedAt(now)
                .setNotBefore(now);
        return jwt.sign();
    }

    public String createToken(Long id, Object bean) {
        DateTime now = DateTime.now();
        DateTime expiresAt = now.offsetNew(DateField.HOUR, 24);
        Map<String, Object> beanedToMap = BeanUtil.beanToMap(bean);
        beanedToMap.put("id", id);
        beanedToMap.put(JWTPayload.NOT_BEFORE, now);
        beanedToMap.put(JWTPayload.ISSUED_AT, now);
        beanedToMap.put(JWTPayload.EXPIRES_AT, expiresAt);
        JWT jwt = JWT.create()
                .setKey(key.getBytes())
                .addPayloads(beanedToMap);
        return jwt.sign();
    }

    public boolean verify(String token) {
        JWT jwt;
        boolean validate = false;
        try {
            jwt = JWTUtil.parseToken(token).setKey(key.getBytes());
            validate = jwt.validate(0);
        } catch (JSONException ignored) {
        }
        logger.info("token 验证结果：{}", validate);
        return validate;
    }

    public JSONObject getPayload(String token) {
        JWT jwt = JWTUtil.parseToken(token).setKey(key.getBytes());
        JSONObject payloads = jwt.getPayloads();
        payloads.remove(JWTPayload.ISSUED_AT);
        payloads.remove(JWTPayload.EXPIRES_AT);
        payloads.remove(JWTPayload.NOT_BEFORE);
        logger.info("token payloads：{}", payloads);
        return payloads;
    }
}
